﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Chinesys.Entities;
using Chinesys.DataModel;
using Chinesys.Domain.BizRules;
using Chinesys.Domain.InputValidations;
using Chinesys.Domain.DataMapper;
using Chinesys.Entities.Constants;

namespace Chinesys.Domain
{
    public static class UserDomain
    {
        public static List<UserEntity> GetAll()
        {
            List<UserEntity> listEntity = new List<UserEntity>();

            using (ChinesysEntities db = new ChinesysEntities())
            {
                List<UserApp> list = (from o in db.UserApps
                                      select o).ToList<UserApp>();


                list.ForEach(x => listEntity.Add(UserDataMapper.UserFromRowToeEntity(x)));
            }

            return listEntity;
        }

        public static UserEntity GetByName(string username)
        {
            UserEntity userResult = null;

            using (ChinesysEntities db = new ChinesysEntities())
            {
                UserApp user = db.UserApps.SingleOrDefault(x => x.UserName == username);

                if (user == null)
                    userResult = null;
                else
                {
                    userResult = UserDataMapper.UserFromRowToeEntity(user);
                    userResult.Role = RoleDataMapper.RoleFromRowToEntity(db.UserAppInRoles.SingleOrDefault(x => x.UserAppId == user.Id).Role);
                }

            }
            return userResult;

        }

        public static UserEntity GetByUserID(int id)
        {
            UserEntity userResult;

            using (ChinesysEntities db = new ChinesysEntities())
            {
                UserApp user = db.UserApps.SingleOrDefault(x => x.Id == id);

                if (user == null)
                    userResult = null;
                else
                {
                    userResult = UserDataMapper.UserFromRowToeEntity(user);
                    userResult.Role = RoleDataMapper.RoleFromRowToEntity(db.UserAppInRoles.SingleOrDefault(x => x.UserAppId == user.Id).Role);
                }
            }

            return userResult;
        }

        public static UserEntity GetByNameAndPass(string username, string password)
        {
            UserEntity userResult;

            using (ChinesysEntities db = new ChinesysEntities())
            {

                UserApp user = db.UserApps.SingleOrDefault(x => x.UserName == username && x.Pass == password);

                if (user == null)
                    userResult = null;
                else
                {
                    userResult = UserDataMapper.UserFromRowToeEntity(user);
                    userResult.Role = RoleDataMapper.RoleFromRowToEntity(user.UserAppInRoles.SingleOrDefault(x => x.UserAppId == user.Id).Role);
                }
            }

            return userResult;
        }

        private static UserEntity Insert(UserEntity user)
        {
            UserApp userRow = UserDataMapper.UserFromEntityToRow(user);
            ChinesysEntities db = new ChinesysEntities();
            db.AddToUserApps(userRow);
            db.SaveChanges();

            user.Id = userRow.Id;
            return user;
        }

        private static UserEntity Update(UserEntity user)
        {
            ChinesysEntities db = new ChinesysEntities();

            UserApp userRow = db.UserApps.SingleOrDefault(x => x.Id == user.Id);

            if (userRow == null)
            {
                throw new BizRulesException("Error El Usuario No se encuentra registrado, no se puede generar la modificación.");
            }

            userRow.Address = user.Address;
            userRow.Email = user.Email;
            userRow.FirstName = user.FirstName;
            userRow.LastName = user.LastName;
            userRow.Newsletter = user.Newsletter;
            userRow.Pass = user.Pass;
            userRow.PhoneOne = user.PhoneOne;
            userRow.PhoneThree = user.PhoneThree;
            userRow.PhoneTwo = user.PhoneTwo;
            userRow.UserName = user.UserName;

            db.SaveChanges();

            return UserDataMapper.UserFromRowToeEntity(userRow);
        }

        public static void SaveCustomerAndCreateAccount(UserEntity user)
        {
            user = Save(user);
            RoleEntity role = RoleDomain.GetByRoleName(Constants.Roles.Customer);
            UserAppInRoleEntity userRole = new UserAppInRoleEntity();
            userRole.CurrentState = RowState.New;
            userRole.RoleId = role.Id;
            userRole.UserAppId = user.Id;
            UserAppInRoleDomain.Save(userRole);
        }

        public static UserEntity UpdatePassword(UserEntity user)
        {
            UserInputValidations validator = new UserInputValidations(user);
            user = Update(user);

            return user;
        }

        public static UserEntity Save(UserEntity user)
        {
            UserInputValidations validator = new UserInputValidations(user);

            if (!validator.IsValid)
                throw new InputValidationException("Hubo errores de validación", validator);

            UserBizRules.OnSave(user);

            if (user.CurrentState == RowState.New)
            {
                user = Insert(user);
            }

            if (user.CurrentState == RowState.Modified)
            {
                user = Update(user);
            }

            return user;
        }
    }
}
